home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / tn3270 KeyMap / keymap.c next >
C/C++ Source or Header  |  1992-04-17  |  39KB  |  1,736 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.4d7  April, 1992
  5.  *  Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #include <QuickDraw.h>
  34. #include <Menus.h>
  35. #include <Dialogs.h>
  36. #include <Memory.h>
  37. #include <SegLoad.h>
  38. #include <Events.h>
  39. #include <TextEdit.h>
  40. #include <ToolUtils.h>
  41. #include <Desk.h>
  42. #include <Windows.h>
  43. #include <Fonts.h>
  44. #include <Files.h>
  45. #include <Devices.h>
  46. #include <Serial.h>
  47. #include <Resources.h>
  48. #include <Packages.h>
  49. #include <Errors.h>
  50. #include <OSEvents.h>
  51. #include <String.h>
  52. #include <Strings.h>
  53. #include <StdIO.h>
  54. #include <CType.h>
  55. #include <StdLib.h>
  56.  
  57.  
  58. #define    NMENUS        3        /* number of defined menus */
  59. #define appleMenu    256
  60. #define    fileMenu    257
  61. #define editMenu    258
  62. #define fileMSize    6        /* size of File menu */
  63.  
  64. #define DEFAULTNUM    129        /* default resource number */
  65.  
  66. typedef struct hexinfo {
  67.     unsigned char *hexname;
  68.     unsigned char hexvalue;
  69.     } hexinfo;
  70.     
  71. typedef struct hexmap {
  72.     unsigned short offset;
  73.     unsigned char stdchar;
  74.     unsigned char aplchar;
  75.     } hexmap;
  76.  
  77. char done;                    /* true to exit program */
  78.                             /* screen control rectangles */
  79.                             /* variables for my window */
  80. MenuHandle myMenus[NMENUS];
  81. struct EventRecord myEvent;
  82. char da_menu;
  83. Rect screenRect;            /* rectangle defining screen */
  84. Rect dragRect;                /* rectangle defining bounds for dragging */
  85. Rect sizeRect;                /* rectangle for resizing windows */
  86. struct Point sfgpoint;        /* standard file dialog locations */
  87. struct Point sfppoint;
  88.  
  89. char defok;                        /* true if good definition read */
  90. unsigned char mapname[64];        /* name of this mapping */
  91. short mapnum;                    /* resource number to use */
  92. SFReply defreply;                /* info. for definition file */
  93. short myresfile;                /* resource file for this program */
  94. short hexcount;                    /* number of entries used in hexbuff */
  95.  
  96. unsigned char keybuffn[128];    /* arrays output to resource in this order */
  97. unsigned char keybuffs[128];
  98. unsigned char keybuffc[128];
  99. unsigned char keybuffcs[128];
  100. unsigned char keybuffo[128];
  101. unsigned char ascbuffn[256];
  102. unsigned char ascbuffs[256];
  103. unsigned char ascbuffc[256];
  104. unsigned char ascbuffcs[256];
  105. unsigned char ascbuffo[256];
  106. hexmap hexbuff[256];
  107.  
  108. void macinit(void);
  109. void macend(void);
  110. void hndmac(void);
  111. void updevent(GrafPtr msgptr);
  112. void menu_upd(void);
  113. void docommand(long mResult);
  114. void appl_menu(void);
  115. void showerr(unsigned char *s);
  116. void showerrln(unsigned char *s, unsigned char *l);
  117. void ctralrt(short a);
  118. OSErr fsrdopen(unsigned char *fname, short vref, short *fref);
  119. void aboutdlg(void);
  120. void ctrwindow(GrafPtr wp);
  121. void framedflt(DialogPtr dlgptr);
  122. OSErr readmap(void);
  123. short newline(unsigned char *text, short lineno);
  124. pascal unsigned short onlydata(FileParam *_pb);
  125. void writetext(void);
  126. OSErr writearray(unsigned char *name, unsigned char *a, short len, short fnum);
  127. OSErr writehex(short fnum);
  128. void writersc(unsigned char new);
  129. OSErr replacedlg(unsigned char *resname);
  130. void showinfo(void);
  131.  
  132. main()
  133. {
  134. macinit();                    /* initialize Mac */
  135. done = 0;
  136. defok = 0;
  137. while (!done) hndmac();        /* handle Mac events and I/O */
  138. macend();
  139. }
  140.  
  141. void macinit(void)
  142. {
  143. short i, bigscreen;
  144.  
  145.             /* set-up general Macintosh environment */
  146. myresfile = CurResFile();
  147. MaxApplZone();                /* set-up for efficient storage use */
  148. for (i=0; i < 4; i++) MoreMasters();
  149. InitGraf(&qd.thePort);
  150. FlushEvents(everyEvent, 0);
  151. InitWindows();
  152. InitFonts();
  153. InitMenus();
  154. InitDialogs(0L);
  155. InitCursor();
  156. TEInit();
  157.  
  158.             /* set-up menus */
  159. for (i=0; i < NMENUS; i++) {
  160.     myMenus[i] = GetMenu(256+i);
  161.     InsertMenu(myMenus[i], 0);
  162.     }
  163. AddResMenu(myMenus[0], 'DRVR');    
  164. da_menu = 0;
  165. appl_menu();
  166.  
  167.             /* center alerts */
  168. ctralrt(256);
  169. ctralrt(260);
  170.  
  171. screenRect = qd.screenBits.bounds;
  172.  
  173. bigscreen = (((screenRect.bottom-screenRect.top) >= 480) &&
  174.              ((screenRect.right-screenRect.left) >= 640)); 
  175.  
  176.             /* calculate standard file dialog location*/
  177. sfppoint.h = (screenRect.right-screenRect.left-304)/2;
  178. sfgpoint.h = (screenRect.right-screenRect.left-348)/2;
  179. if (bigscreen) {
  180.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/3;
  181.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/3;
  182.     }
  183. else {
  184.     sfppoint.v = (screenRect.bottom-screenRect.top-184)/2;
  185.     sfgpoint.v = (screenRect.bottom-screenRect.top-200)/2;
  186.     }
  187.  
  188. SetRect(&dragRect, 0, 24, screenRect.right-4, screenRect.bottom-4);
  189.  
  190. SetRect(&sizeRect, 50, 25, screenRect.right+1, screenRect.bottom+1);
  191. }
  192.  
  193. void macend(void)
  194. {
  195. }
  196.  
  197. void hndmac(void)
  198. {
  199. OSErr rc;
  200. short code;
  201. GrafPtr gp;
  202. unsigned short h, w;
  203. long l;
  204. struct WindowRecord *fw;
  205. WindowPtr whichWindow;
  206. char frontda;
  207.  
  208. rc = GetNextEvent(everyEvent, &myEvent);
  209. if (rc == 0)                        /* FALSE from GNE */
  210.     switch(myEvent.what) {
  211.         case nullEvent:
  212.                 fw = (WindowRecord *)FrontWindow();
  213.                 frontda = fw->windowKind < 0;
  214.                 if (frontda) {
  215.                     if (!da_menu) {
  216.                         da_menu = 1;
  217.                         SetItem(myMenus[1], fileMSize, "\pClose");
  218.                         appl_menu();
  219.                         }
  220.                     }
  221.                 else {
  222.                     if (da_menu) {
  223.                         da_menu = 0;
  224.                         SetItem(myMenus[1], fileMSize, "\pQuit");
  225.                         appl_menu();
  226.                         }
  227.                     }
  228.                 SystemTask();    /* run DAs, etc. */
  229.                 break;
  230.         default:
  231.                 return;
  232.         }
  233. else switch(myEvent.what) {            /* TRUE from GNE */
  234.         case mouseDown:
  235.             code = FindWindow(myEvent.where, &whichWindow);
  236.             switch (code) {
  237.             case inMenuBar:
  238.                 menu_upd();
  239.                 docommand(MenuSelect(myEvent.where));
  240.                 break;
  241.             case inSysWindow:
  242.                 SystemClick(&myEvent, whichWindow);
  243.                 break;
  244.             case inDrag:
  245.                 if (whichWindow == FrontWindow())
  246.                     DragWindow(whichWindow, myEvent.where,
  247.                                 &dragRect);
  248.                 else SelectWindow(whichWindow);
  249.                 break;
  250.             case inGoAway:
  251.                 break;
  252.             case inGrow:
  253.                 if (whichWindow == FrontWindow()) {
  254.                     GetPort(&gp);
  255.                     SetPort(whichWindow);
  256.                     l = GrowWindow(whichWindow, myEvent.where,
  257.                                 &sizeRect);
  258.                     h = l >> 16;
  259.                     w = l & 0x0000ffffL;
  260.                     SizeWindow(whichWindow, w, h, 0x100);
  261.                     SetPort(gp);
  262.                     }
  263.                 break;
  264.             case inContent:
  265.                 if (whichWindow != FrontWindow()) {
  266.                     SelectWindow(whichWindow);
  267.                     break;
  268.                     }
  269.                 break;
  270.  
  271.             case inZoomIn:
  272.             case inZoomOut:
  273.                 if (TrackBox(whichWindow, myEvent.where, code)) {
  274.                     if (((WindowPeek)whichWindow)->dataHandle == 0) break;
  275.                     GetPort(&gp);
  276.                     SetPort(whichWindow);
  277.                     EraseRect(&(((struct WindowRecord *)whichWindow)->port.portRect));
  278.                     ZoomWindow(whichWindow, code, 0);
  279.                     SetPort(gp);
  280.                     }
  281.                 break;
  282.  
  283.             default:
  284.                 break;
  285.             }
  286.             break;
  287.  
  288.         case mouseUp:
  289.             break;
  290.  
  291.         case keyDown:
  292.         case autoKey:
  293.             break;
  294.  
  295.         case activateEvt:
  296.             break;
  297.  
  298.         case updateEvt:
  299.             updevent((GrafPtr)myEvent.message);
  300.             break;
  301.  
  302.         case app4Evt:
  303.             break;
  304.  
  305.         default:    break;
  306.         }
  307. }
  308.  
  309. void updevent(GrafPtr msgptr)
  310. {
  311. GrafPtr gp;
  312.  
  313. GetPort(&gp);
  314. SetPort(msgptr);
  315. BeginUpdate(msgptr);
  316. EndUpdate(msgptr);
  317. SetPort(gp);
  318. }
  319.  
  320. void menu_upd(void)
  321. {
  322. short i;
  323.  
  324. if (da_menu) {
  325.     for (i = 1; i < fileMSize; i++)
  326.         DisableItem(myMenus[1], i);
  327.     CheckItem(myMenus[1], fileMSize, 0);
  328.     }
  329. else {
  330.     if (defok) {
  331.         for (i = 1; i < fileMSize; i++)
  332.             EnableItem(myMenus[1], i);
  333.         }
  334.     else {
  335.         EnableItem(myMenus[1], 1);
  336.         for (i = 2; i < fileMSize; i++)
  337.             DisableItem(myMenus[1], i);
  338.         }
  339.     CheckItem(myMenus[1], fileMSize, done << 8);
  340.     }
  341. }
  342.  
  343. void docommand(long mResult)
  344. {
  345. register short theItem, theMenu;
  346. unsigned char name[40];
  347. WindowRecord * fw;
  348. short i;
  349. static char nullstr[1] = {0};
  350. OSErr rc;
  351.  
  352. theMenu = mResult >> 16;
  353. theItem = mResult & 0xff;
  354. switch(theMenu) {
  355.     case appleMenu:
  356.         if (theItem == 2) break;
  357.         if (theItem == 1) {
  358.             aboutdlg();
  359.             break;
  360.             }
  361.         GetItem(myMenus[0], theItem, name);
  362.         OpenDeskAcc(name);
  363.         break;
  364.     case fileMenu:
  365.         switch (theItem) {
  366.             case 1:
  367.                     rc = readmap();
  368.                     defok = (rc == 0);
  369.                     break;
  370.             case 2:
  371.                     showinfo();
  372.                     break;
  373.             case 3:
  374.                     writetext();
  375.                     break;
  376.             case 4:
  377.                     writersc(0);
  378.                     break;
  379.             case 5:
  380.                     writersc(1);
  381.                     break;
  382.             case 6:
  383.                     if (!da_menu) {
  384.                         done ^= 1;
  385.                         break;
  386.                         }
  387.                     else {
  388.                         fw = (WindowRecord *)FrontWindow();
  389.                         i = fw->windowKind;
  390.                         if (i<0) CloseDeskAcc(i);
  391.                         }
  392.             default: break;
  393.             }
  394.         break;
  395.     case editMenu:
  396.         SystemEdit(theItem-1);
  397.         break;
  398.     default:
  399.         break;
  400.     }
  401.     HiliteMenu(0);
  402.     appl_menu();
  403. }
  404.  
  405. void appl_menu(void)            /* enable correct application menus */
  406. {
  407. static char last_da = 2;    /* init to invalid value */
  408.  
  409. /* skip drawing menu if no changes from last time */
  410. if (last_da == da_menu) return;
  411. last_da = da_menu;        /* save values for next time */
  412.  
  413. if (da_menu) {
  414.     EnableItem(myMenus[2], 0);
  415.     }
  416. else {
  417.     DisableItem(myMenus[2], 0);
  418.     }
  419. DrawMenuBar();
  420. }
  421.  
  422. void showerr(unsigned char *s)
  423. {
  424. static char nullstr[1] = {0};
  425.  
  426. c2pstr(s);
  427. ParamText(s, nullstr, nullstr, nullstr);
  428. p2cstr(s);
  429. StopAlert(256, 0L);
  430. ParamText(nullstr, nullstr, nullstr, nullstr);
  431. }
  432.  
  433. void showerrln(unsigned char *s, unsigned char *l)
  434. {
  435. static char nullstr[1] = {0};
  436.  
  437. c2pstr(s);
  438. c2pstr(l);
  439. ParamText(s, l, nullstr, nullstr);
  440. p2cstr(s);
  441. p2cstr(l);
  442. StopAlert(260, 0L);
  443. ParamText(nullstr, nullstr, nullstr, nullstr);
  444. }
  445.  
  446. void ctralrt(short a)        /* a = alert number */
  447. {
  448. Handle reshnd;
  449. struct Rect * rptr;
  450. short scrhsize, scrvsize;
  451. short ahsize, avsize;
  452.  
  453. CouldAlert(a);        /* read alert into memory and make unpurgeable */
  454. reshnd = GetResource('ALRT', a);
  455. if (reshnd == 0) return;
  456. rptr = (struct Rect *)*reshnd;
  457. scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
  458. scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  459. ahsize = rptr->right - rptr->left;
  460. avsize = rptr->bottom - rptr->top;
  461. rptr->top = (scrvsize-avsize)/3;
  462. rptr->left = (scrhsize-ahsize)/2;
  463. rptr->bottom = rptr->top + avsize;
  464. rptr->right = rptr->left + ahsize;
  465. }
  466.  
  467. OSErr fsrdopen(unsigned char *fname, short vref, short *fref)
  468. {                                        /* open file read-only */
  469. IOParam pbi;
  470. OSErr rc;
  471.  
  472. /* initialize parameter block */
  473. memset(&pbi, 0, sizeof(IOParam));
  474.  
  475. pbi.ioNamePtr = (StringPtr)fname;
  476. pbi.ioVRefNum = vref;
  477. pbi.ioPermssn = fsRdPerm;
  478. rc = PBOpen((ParmBlkPtr)&pbi, 0);
  479. *fref = pbi.ioRefNum;
  480. return(rc);
  481. }
  482.  
  483. void aboutdlg(void)
  484. {
  485. DialogPtr dlgptr;
  486. short itemHit;
  487. unsigned char **version;
  488. static char nullstr[1] = {0};
  489.  
  490. dlgptr = GetNewDialog(257, (Ptr)0L, (WindowPtr)-1L);
  491. ctrwindow(dlgptr);
  492. version = GetResource('GFTK', 0);
  493. if (version == 0L) {
  494.     DisposDialog(dlgptr);
  495.     return;
  496.     }
  497. ParamText(*version, nullstr, nullstr, nullstr);
  498. ShowWindow(dlgptr);
  499.  
  500. /* frame the default selection */
  501. framedflt(dlgptr);
  502.  
  503. ModalDialog(0L, &itemHit);
  504. DisposDialog(dlgptr);
  505. ParamText(nullstr, nullstr, nullstr, nullstr);
  506. }
  507.  
  508. void ctrwindow(GrafPtr wp)
  509. {
  510. short scrhsize, scrvsize;
  511. short whsize, wvsize;
  512.  
  513. scrhsize = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
  514. scrvsize = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top;
  515. whsize = wp->portRect.right-wp->portRect.left;
  516. wvsize = wp->portRect.bottom - wp->portRect.top;
  517. MoveWindow(wp, (scrhsize-whsize)/2, (scrvsize-wvsize)/3, 0);
  518. }
  519.  
  520. void framedflt(DialogPtr dlgptr)
  521. {
  522. short gtype;
  523. Handle gitem;
  524. Rect gbox;
  525. GrafPtr gp;
  526.  
  527. GetDItem(dlgptr, 1, >ype, &gitem, &gbox);
  528. GetPort(&gp);
  529. SetPort(dlgptr);
  530. PenSize(3,3);
  531. InsetRect(&gbox, -4, -4);
  532. FrameRoundRect(&gbox, 16, 16);
  533. SetPort(gp);
  534. }
  535.  
  536. OSErr readmap(void)        /* read definition file to define name and arrays */
  537. {
  538. Point where;
  539. pascal unsigned short (*fileFilter)();
  540. short numTypes;
  541. SFReply reply;
  542. SFTypeList typeList;
  543. DlgHookProcPtr dlgHook;
  544. pascal unsigned short onlydata();
  545. unsigned char errtext[256];
  546. short fref;
  547. OSErr rc;
  548. short linenum, linerc;
  549. unsigned char textchar;
  550. unsigned char textline[256];
  551. short textlen;
  552. unsigned char commentflag;
  553. long fcount;
  554.  
  555. /* open definition file */
  556.  
  557. where = sfgpoint;
  558. dlgHook = 0;
  559. fileFilter = onlydata;
  560. numTypes = 2;
  561. typeList[0] = 'TEXT';
  562. typeList[1] = 'ttro';
  563. SFGetFile(where, "\p", (FileFilterProcPtr)fileFilter, numTypes,
  564.     &typeList, dlgHook, &reply);
  565. if (reply.good == 0) return(defok == 0);    /* user selected "cancel" */
  566. defreply = reply;                /* save good data */
  567. rc = fsrdopen(&defreply.fName, defreply.vRefNum, &fref);
  568. if (rc != 0) {
  569.     p2cstr(&defreply.fName);
  570.     sprintf(errtext, "Error %d opening %s", rc, &defreply.fName);
  571.     c2pstr(&defreply.fName);
  572.     showerr(errtext);
  573.     return(rc);
  574.     }
  575.     
  576. /* read file and process each line */
  577. strcpy(mapname, "unnamed");        /* set default name */
  578. mapnum = DEFAULTNUM;            /* set default number */
  579.                                 /* initialize mapping arrays */
  580. memset(keybuffn, 0, 128); 
  581. memset(keybuffs, 0, 128); 
  582. memset(keybuffc, 0, 128); 
  583. memset(keybuffcs, 0, 128);
  584. memset(keybuffo, 0, 128);
  585. memset(ascbuffn, 0, 256);
  586. memset(ascbuffs, 0, 256);
  587. memset(ascbuffc, 0, 256);
  588. memset(ascbuffcs, 0, 256);
  589. memset(ascbuffo, 0, 256);
  590. memset(hexbuff, 0, sizeof(hexmap)*256);
  591. hexcount = 0;
  592. linenum = 0;
  593. textlen = 0;
  594. commentflag = 0;
  595. fcount = 1;
  596. linerc = 0;
  597. rc = FSRead(fref, &fcount, &textchar);
  598. while ((rc == 0) && (linerc == 0)) {    /* process new character */
  599.     switch (textchar) {
  600.         case 0x0d:                /* end of line */
  601.                 linenum++;
  602.                 textline[textlen] = 0;
  603.                 linerc = newline(textline, linenum);
  604.                 textlen = 0;
  605.                 commentflag = 0;
  606.                 break;
  607.         case '#':                /* start of comment */
  608.                 commentflag = 1;
  609.                 break;
  610.         case 0x00:                /* null */
  611.         case 0x09:                /* tab */
  612.         case 0x0a:                /* linefeed */
  613.         case 0x0b:                /* vertical tab */
  614.         case 0x0c:                /* formfeed */
  615.         case 0x20:                /* blank */
  616.                 break;
  617.         default:
  618.                 if (commentflag) break;
  619.                 if (textlen == 255) {
  620.                     sprintf(errtext, 
  621.                         "Line %d truncated to first 255 characters:",
  622.                         linenum+1);
  623.                     textline[textlen] = 0;
  624.                     showerrln(errtext, textline);
  625.                     commentflag = 1;
  626.                     break;
  627.                     }
  628.                 textline[textlen++] = textchar;
  629.                 break;
  630.         }
  631.     fcount = 1;
  632.     rc = FSRead(fref, &fcount, &textchar);
  633.     }
  634. if ((rc != eofErr) && (rc != 0)) {
  635.     sprintf(errtext, "Error %d reading definition file.", rc);
  636.     showerr(errtext);
  637.     FSClose(fref);
  638.     return(rc);
  639.     }
  640. else if ((textlen > 0) && (linerc == 0)) {
  641.     linenum++;
  642.     textline[textlen] = 0;
  643.     linerc = newline(textline, linenum);
  644.     }
  645. FSClose(fref);
  646. return(linerc);
  647. }
  648.  
  649. short newline(unsigned char *text, short lineno)
  650. {
  651. unsigned char errtext[256];
  652. short textlen, idlen, modlen;
  653. unsigned char textbuff[64];
  654. register int i, j;
  655. unsigned char c, usflag, state;
  656. unsigned char valtype, valnum, idnum, hexnum;
  657. unsigned char id[64];
  658. unsigned char mod[64];
  659. unsigned char * tabptr1, * tabptr2;
  660. unsigned short taboff1, taboff2;
  661. static unsigned char * modnames[] = {
  662.     "NORMAL", "SHIFT", "COMMAND", "COMMAND-SHIFT", "OPTION"};
  663. static unsigned char * namelist[] = {
  664.     /* 000 */    "SPACE",
  665.     /* 001 */    "CENT",
  666.     /* 002 */    "PERIOD",
  667.     /* 003 */    "LESS",
  668.     /* 004 */    "LPAREN",
  669.     /* 005 */    "PLUS",
  670.     /* 006 */    "OR",
  671.     /* 007 */    "AMPERSAND",
  672.     /* 008 */    "EXCLAIM",
  673.     /* 009 */    "DOLLAR",
  674.     /* 010 */    "ASTERISK",
  675.     /* 011 */    "RPAREN",
  676.     /* 012 */    "SEMI",
  677.     /* 013 */    "NOT",
  678.     /* 014 */    "MINUS",
  679.     /* 015 */    "SLASH",
  680.     /* 016 */    "VERTICAL",
  681.     /* 017 */    "COMMA",
  682.     /* 018 */    "PERCENT",
  683.     /* 019 */    "UNDERSCORE",
  684.     /* 020 */    "GREATER",
  685.     /* 021 */    "QUESTION",
  686.     /* 022 */    "ACCENT",
  687.     /* 023 */    "COLON",
  688.     /* 024 */    "POUND",
  689.     /* 025 */    "AT",
  690.     /* 026 */    "APOSTROPHE",
  691.     /* 027 */    "EQUAL",
  692.     /* 028 */    "DBLQUOTE",
  693.     /* 029 */    "LCA",
  694.     /* 030 */    "LCB",
  695.     /* 031 */    "LCC",
  696.     /* 032 */    "LCD",
  697.     /* 033 */    "LCE",
  698.     /* 034 */    "LCF",
  699.     /* 035 */    "LCG",
  700.     /* 036 */    "LCH",
  701.     /* 037 */    "LCI",
  702.     /* 038 */    "LCJ",
  703.     /* 039 */    "LCK",
  704.     /* 040 */    "LCL",
  705.     /* 041 */    "LCM",
  706.     /* 042 */    "LCN",
  707.     /* 043 */    "LCO",
  708.     /* 044 */    "LCP",
  709.     /* 045 */    "LCQ",
  710.     /* 046 */    "LCR",
  711.     /* 047 */    "TILDE",
  712.     /* 048 */    "LCS",
  713.     /* 049 */    "LCT",
  714.     /* 050 */    "LCU",
  715.     /* 051 */    "LCV",
  716.     /* 052 */    "LCW",
  717.     /* 053 */    "LCX",
  718.     /* 054 */    "LCY",
  719.     /* 055 */    "LCZ",
  720.     /* 056 */    "LBRACK",
  721.     /* 057 */    "RBRACK",
  722.     /* 058 */    "LBRACE",
  723.     /* 059 */    "A",
  724.     /* 060 */    "B",
  725.     /* 061 */    "C",
  726.     /* 062 */    "D",
  727.     /* 063 */    "E",
  728.     /* 064 */    "F",
  729.     /* 065 */    "G",
  730.     /* 066 */    "H",
  731.     /* 067 */    "I",
  732.     /* 068 */    "RBRACE",
  733.     /* 069 */    "J",
  734.     /* 070 */    "K",
  735.     /* 071 */    "L",
  736.     /* 072 */    "M",
  737.     /* 073 */    "N",
  738.     /* 074 */    "O",
  739.     /* 075 */    "P",
  740.     /* 076 */    "Q",
  741.     /* 077 */    "R",
  742.     /* 078 */    "BACKSLASH",
  743.     /* 079 */    "S",
  744.     /* 080 */    "T",
  745.     /* 081 */    "U",
  746.     /* 082 */    "V",
  747.     /* 083 */    "W",
  748.     /* 084 */    "X",
  749.     /* 085 */    "Y",
  750.     /* 086 */    "Z",
  751.     /* 087 */    "0",
  752.     /* 088 */    "1",
  753.     /* 089 */    "2",
  754.     /* 090 */    "3",
  755.     /* 091 */    "4",
  756.     /* 092 */    "5",
  757.     /* 093 */    "6",
  758.     /* 094 */    "7",
  759.     /* 095 */    "8",
  760.     /* 096 */    "9",
  761.     /* 097 */    "A_",
  762.     /* 098 */    "B_",
  763.     /* 099 */    "C_",
  764.     /* 100 */    "D_",
  765.     /* 101 */    "E_",
  766.     /* 102 */    "F_",
  767.     /* 103 */    "G_",
  768.     /* 104 */    "H_",
  769.     /* 105 */    "I_",
  770.     /* 106 */    "J_",
  771.     /* 107 */    "K_",
  772.     /* 108 */    "L_",
  773.     /* 109 */    "M_",
  774.     /* 110 */    "N_",
  775.     /* 111 */    "O_",
  776.     /* 112 */    "P_",
  777.     /* 113 */    "Q_",
  778.     /* 114 */    "R_",
  779.     /* 115 */    "S_",
  780.     /* 116 */    "T_",
  781.     /* 117 */    "U_",
  782.     /* 118 */    "V_",
  783.     /* 119 */    "W_",
  784.     /* 120 */    "X_",
  785.     /* 121 */    "Y_",
  786.     /* 122 */    "Z_",
  787.     /* 123 */    "I-BEAM",
  788.     /* 124 */    "DEL-TILDE",
  789.     /* 125 */    "GRADE-DOWN",
  790.     /* 126 */    "GRADE-UP",
  791.     /* 127 */    "VERT-ROTATE",
  792.     /* 128 */    "TRANSPOSE",
  793.     /* 129 */    "HOR-ROTATE",
  794.     /* 130 */    "LOGARITHM",
  795.     /* 131 */    "NOR",
  796.     /* 132 */    "NAND",
  797.     /* 133 */    "APL-EXCLAIM",
  798.     /* 134 */    "DOMINO",
  799.     /* 135 */    "QUOTE-QUAD",
  800.     /* 136 */    "DELTA_",
  801.     /* 137 */    "FORMAT",
  802.     /* 138 */    "EXECUTE",
  803.     /* 139 */    "LAMP",
  804.     /* 140 */    "EXPAND",
  805.     /* 141 */    "COMPRESS",
  806.     /* 142 */    "ENTER",
  807.     /* 143 */    "PF1",
  808.     /* 144 */    "PF2",
  809.     /* 145 */    "PF3",
  810.     /* 146 */    "PF4",
  811.     /* 147 */    "PF5",
  812.     /* 148 */    "PF6",
  813.     /* 149 */    "PF7",
  814.     /* 150 */    "PF8",
  815.     /* 151 */    "PF9",
  816.     /* 152 */    "PF10",
  817.     /* 153 */    "PF11",
  818.     /* 154 */    "PF12",
  819.     /* 155 */    "PF13",
  820.     /* 156 */    "PF14",
  821.     /* 157 */    "PF15",
  822.     /* 158 */    "PF16",
  823.     /* 159 */    "PF17",
  824.     /* 160 */    "PF18",
  825.     /* 161 */    "PF19",
  826.     /* 162 */    "PF20",
  827.     /* 163 */    "PF21",
  828.     /* 164 */    "PF22",
  829.     /* 165 */    "PF23",
  830.     /* 166 */    "PF24",
  831.     /* 167 */    "PA1",
  832.     /* 168 */    "PA2",
  833.     /* 169 */    "PA3",
  834.     /* 170 */    "CLEAR",
  835.     /* 171 */    "TREQ",
  836.     /* 172 */    "CURSEL",
  837.     /* 173 */    "UP",
  838.     /* 174 */    "DOWN",
  839.     /* 175 */    "LEFT",
  840.     /* 176 */    "RIGHT",
  841.     /* 177 */    "TAB",
  842.     /* 178 */    "BACKTAB",
  843.     /* 179 */    "NEWLINE",
  844.     /* 180 */    "HOME",
  845.     /* 181 */    "ERASE-EOF",
  846.     /* 182 */    "ERASE-INPUT",
  847.     /* 183 */    "INSERT-MODE",
  848.     /* 184 */    "DELETE-CHAR",
  849.     /* 185 */    "RESET",
  850.     /* 186 */    "DUP",
  851.     /* 187 */    "FIELD-MARK",
  852.     /* 188 */    "APL-MODE",
  853.     /* 189 */    "INSERT-CHAR",
  854.     /* 190 */    "RUB-OUT",
  855.     /* 191 */    "UP*2",
  856.     /* 192 */    "DOWN*2",
  857.     /* 193 */    "LEFT*2",
  858.     /* 194 */    "RIGHT*2",
  859.     /* 195 */    "CURSOR-POS",
  860.     /* 196 */    "PROG-RESET",
  861.     /* 197 */    "PRINT-SCREEN",
  862.     };
  863.     
  864. static hexinfo hexlist[] = {
  865.     {"SUBFIELD_DELIMITER", 0x1F},
  866.     {"END_OF_LINE", 0x2A},
  867.     {"START_OF_MESSAGE", 0x38},
  868.     {"PARAGRAPH", 0x39},
  869.     {"DAGGER", 0x3A},
  870.     {"DOUBLE_DAGGER", 0x3B},
  871.     {"POLISH_L_UPPER", 0x41},
  872.     {"SCANDINAVIAN_O_UPPER", 0x42},
  873.     {"D_WITH_CROSSBAR_UPPER", 0x43},
  874.     {"ICELANDIC_THORN_UPPER", 0x44},
  875.     {"DIGRAPH_AE_UPPER", 0x45},
  876.     {"DIGRAPH_OE_UPPER", 0x46},
  877.     {"O-HOOK_UPPER", 0x47},
  878.     {"U-HOOK_UPPER", 0x48},
  879.     {"SOFT_SIGN", 0x49},
  880.     {"POLISH_L_LOWER", 0x51},
  881.     {"SCANDINAVIAN_O_LOWER", 0x52},
  882.     {"D_WITH_CROSSBAR_LOWER", 0x53},
  883.     {"ICELANDIC_THORN_LOWER", 0x54},
  884.     {"DIGRAPH_AE_LOWER", 0x55},
  885.     {"DIGRAPH_OE_LOWER", 0x56},
  886.     {"O-HOOK_LOWER", 0x57},
  887.     {"U-HOOK_LOWER", 0x58},
  888.     {"HARD_SIGN", 0x59},
  889.     {"AYN", 0x62},
  890.     {"ALIF", 0x63},
  891.     {"DOT_IN_MIDDLE_OF_LINE", 0x64},
  892.     {"TURKISH_I_LOWER", 0x65},
  893.     {"MUSICAL_FLAT", 0x66},
  894.     {"SUBSCRIPT_PATENT_MARK", 0x67},
  895.     {"ETH", 0x68},
  896.     {"PLUS_OR_MINUS", 0x69},
  897.     {"SUB0", 0x70},
  898.     {"SUB1", 0x71},
  899.     {"SUB2", 0x72},
  900.     {"SUB3", 0x73},
  901.     {"SUB4", 0x74},
  902.     {"SUB5", 0x75},
  903.     {"SUB6", 0x76},
  904.     {"SUB7", 0x77},
  905.     {"SUB8", 0x78},
  906.     {"SCRIPT_L", 0x80},
  907.     {"CIRCLE_ABOVE", 0x8A},
  908.     {"SUPERIOR_DOT", 0x8B},
  909.     {"UMLAUT", 0x8C},
  910.     {"CANDRABINDU", 0x8D},
  911.     {"LIGATURE_FIRST_HALF", 0x8E},
  912.     {"DOUBLE_TILDE_FIRST_HALF", 0x8F},
  913.     {"SUB9", 0x90},
  914.     {"GRAVE", 0x9A},
  915.     {"ACUTE", 0x9B},
  916.     {"ALA_CIRCUMFLEX", 0x9C},
  917.     {"HACEK", 0x9D},
  918.     {"LIGATURE_SECOND_HALF", 0x9E},
  919.     {"DOUBLE_TILDE_SECOND_HALF", 0x9F},
  920.     {"ALA_DAGGER", 0xA0},
  921.     {"SUB_PLUS", 0xAA},
  922.     {"SUB_LPAREN", 0xAB},
  923.     {"PINCUSHION", 0xAC},
  924.     {"SUB_MINUS", 0xAE},
  925.     {"SUB_RPAREN", 0xAF},
  926.     {"SUP0", 0xB0},
  927.     {"SUP1", 0xB1},
  928.     {"SUP2", 0xB2},
  929.     {"SUP3", 0xB3},
  930.     {"SUP4", 0xB4},
  931.     {"SUP5", 0xB5},
  932.     {"SUP6", 0xB6},
  933.     {"SUP7", 0xB7},
  934.     {"SUP8", 0xB8},
  935.     {"SUP9", 0xB9},
  936.     {"SUP_PLUS", 0xBA},
  937.     {"SUP_LPAREN", 0xBB},
  938.     {"ASPER", 0xBC},
  939.     {"SUP_MINUS", 0xBE},
  940.     {"SUP_RPAREN", 0xBF},
  941.     {"CIRCLE_BELOW", 0xCA},
  942.     {"DOT_BELOW", 0xCB},
  943.     {"DOUBLE_DOT_BELOW", 0xCC},
  944.     {"BREVE", 0xCD},
  945.     {"ALA_TILDE", 0xCE},
  946.     {"PSEUDO_QUESTION", 0xCF},
  947.     {"CEDILLA", 0xDA},
  948.     {"HIGH_COMMA_CENTERED", 0xDB},
  949.     {"RIGHT_HOOK", 0xDC},
  950.     {"UPADHMANIYA", 0xDD},
  951.     {"MACRON", 0xDE},
  952.     {"DOUBLE_ACUTE", 0xDF},
  953.     {"BRITISH_POUND", 0xE1},
  954.     {"RIGHT_CEDILLA", 0xEA},
  955.     {"HIGH_COMMA_OFF_CENTER", 0xEB},
  956.     {"LEFT_HOOK/TAIL", 0xEC},
  957.     {"ALA_UNDERSCORE", 0xED},
  958.     {"DOUBLE_UNDERSCORE", 0xEE},
  959.     {"ALA_ALPHA", 0xFA},
  960.     {"ALA_BETA", 0xFB},
  961.     {"ALA_GAMMA", 0xFC},
  962.     {"YEN", 0xFD},
  963.     {"PESO", 0xFE}};
  964.  
  965. textlen = strlen(text);
  966.  
  967. /* skip null lines */
  968. if (textlen == 0) return (0);
  969.  
  970. /* check for name definition line */
  971. if (textlen > 5) {
  972.     for (i=0; i < 5; i++) 
  973.         textbuff[i] = toupper(text[i]);
  974.     if (strncmp(textbuff, "NAME:", 5) == 0) {
  975.         i = 0;
  976.         j = i + 5;
  977.         usflag = 0;
  978.         while (i < 63) {
  979.             c = text[j++];
  980.             if (usflag) {
  981.                 if (c == '_') {
  982.                     mapname[i++] = '_';
  983.                     }
  984.                 else {
  985.                     mapname[i++] = ' ';
  986.                     if (i < 63) {
  987.                         mapname[i++] = c;
  988.                         if (c == 0) break;
  989.                         }
  990.                     }
  991.                 usflag = 0;
  992.                 }
  993.             else if (c == '_') {
  994.                 usflag = 1;
  995.                 }
  996.             else {
  997.                 mapname[i++] = c;
  998.                 if (c == 0) break;
  999.                 }
  1000.             }
  1001.         mapname[63] = 0;
  1002.         return(0);
  1003.         }
  1004.     }
  1005.  
  1006. /* check for number definition line */
  1007. if (textlen > 7) {
  1008.     for (i=0; i < 7; i++) 
  1009.         textbuff[i] = toupper(text[i]);
  1010.     if (strncmp(textbuff, "NUMBER:", 7) == 0) {
  1011.         c = 0;
  1012.         for (i=7; i < textlen; i++) {
  1013.             c = text[i];
  1014.             if ((c < '0') || (c > '9')) break;
  1015.             }
  1016.         if ((c >= '0') && (c <= '9')) {
  1017.             mapnum = atoi(text+7);
  1018.             return(0);
  1019.             }
  1020.         }
  1021.     }
  1022.  
  1023. /* process mapping definition line */
  1024.  
  1025. state = 0;
  1026. idlen = modlen = 0;
  1027. for (i=0; i < textlen; i++) {
  1028.     c = text[i];
  1029.     switch(state) {
  1030.         case 0:                    /* first character */
  1031.                 if (c == '=') {
  1032.                     state = 99;
  1033.                     }
  1034.                 else {
  1035.                     id[idlen++] = toupper(c);
  1036.                     state = 1;
  1037.                     }
  1038.                 break;
  1039.         case 1:                    /* characters of id */
  1040.                 if (c == '=') {
  1041.                     id[idlen] = 0;
  1042.                     state = 2;
  1043.                     }
  1044.                 else {
  1045.                     if (idlen < 63) id[idlen++] = toupper(c);
  1046.                     else state = 99;
  1047.                     }
  1048.                 break;
  1049.         case 2:                    /* characters in modifier */
  1050.                 if (c == '\'') {
  1051.                     mod[modlen] = 0;
  1052.                     state = 3;
  1053.                     }
  1054.                 else if (c == '"') {
  1055.                     mod[modlen] = 0;
  1056.                     state = 5;
  1057.                     }
  1058.                 else {
  1059.                     if (modlen < 63) mod[modlen++] = toupper(c);
  1060.                     else state = 99;
  1061.                     }
  1062.                 break;
  1063.         case 3:                    /* literal character value */
  1064.                 valtype = 0;
  1065.                 valnum = c;
  1066.                 state = 4;
  1067.                 break;
  1068.         case 4:                    /* end of character literal */
  1069.                 if (c == '\'') state = 9;
  1070.                 else state = 99;
  1071.                 break;
  1072.         case 5:                    /* start of hex string */
  1073.                 c = toupper(c);
  1074.                 if ((c >= 'A') && (c <= 'F')) {
  1075.                     valtype = 0;
  1076.                     valnum = (c - 'A' + 10) << 4;
  1077.                     state = 7;
  1078.                     }
  1079.                 else if ((c >= '0') && (c <= '9')) {
  1080.                     valtype = 0;
  1081.                     valnum = (c - '0') << 4;
  1082.                     state = 7;
  1083.                     }
  1084.                 else if (c == 'K') {
  1085.                     valtype = 6;
  1086.                     state = 6;
  1087.                     }
  1088.                 else state = 99;
  1089.                 break;
  1090.         case 6:                    /* after "K" in string */
  1091.                 c = toupper(c);
  1092.                 if ((c >= 'A') && (c <= 'F')) {
  1093.                     valnum = (c - 'A' + 10) << 4;
  1094.                     state = 7;
  1095.                     }
  1096.                 else if ((c >= '0') && (c <= '9')) {
  1097.                     valnum = (c - '0') << 4;
  1098.                     state = 7;
  1099.                     }
  1100.                 else state = 99;
  1101.                 break;
  1102.         case 7:                    /* after first hex digit */
  1103.                 c = toupper(c);
  1104.                 if ((c >= 'A') && (c <= 'F')) {
  1105.                     valnum += c - 'A' + 10;
  1106.                     state = 8;
  1107.                     }
  1108.                 else if ((c >= '0') && (c <= '9')) {
  1109.                     valnum += c - '0';
  1110.                     state = 8;
  1111.                     }
  1112.                 else state = 99;
  1113.                 break;
  1114.         case 8:                    /* end of hex string */
  1115.                 if (c == '"') state = 9;
  1116.                 else state = 99;
  1117.                 break;
  1118.         case 9:                    /* after complete definition */
  1119.         default:
  1120.                 state = 99;
  1121.                 break;
  1122.         }
  1123.     if (state == 99) break;        /* syntax error */
  1124.     }
  1125.  
  1126. if (state != 9) {            /* error if not in finishing state */
  1127.     sprintf(errtext, "Syntax error in definition file at line %d:",
  1128.         lineno);
  1129.     showerrln(errtext, text);
  1130.     return(4);
  1131.     }
  1132.     
  1133. /* apply modifier, if any to valtype */
  1134. if (modlen > 0) {
  1135.     j = -1;
  1136.     for (i=0; i < sizeof(modnames) >> 2; i++) {
  1137.         if (strcmp(mod, modnames[i]) == 0) {
  1138.             j = i;
  1139.             break;
  1140.             }
  1141.         }
  1142.     if (j < 0) {
  1143.         sprintf(errtext, "Invalid modifier value '%s' at line %d:",
  1144.             mod, lineno);
  1145.         showerrln(errtext, text);
  1146.         return(8);
  1147.         }
  1148.     else valtype += j+1;
  1149.     }
  1150.     
  1151. /* check that keycode value is legal */
  1152. if ((valtype >= 6) && (valnum > 127)) {
  1153.     sprintf(errtext, "Key code '%x' exceeds 7f at line %d:",
  1154.         valnum, lineno);
  1155.     showerrln(errtext, text);
  1156.     return(12);
  1157.     }
  1158.     
  1159. /* convert function id table index */
  1160. j = -1;
  1161. for (i=0; i < sizeof(namelist) >> 2; i++) {
  1162.     if (strcmp(id, namelist[i]) == 0) {
  1163.         j = i;
  1164.         break;
  1165.         }
  1166.     }
  1167.  
  1168. if (j >= 0) {
  1169.     idnum = j;
  1170.     hexnum = 0;
  1171.     }
  1172. else {            /* search hex name table */
  1173.     for (i=0; i < sizeof(hexlist)/sizeof(hexinfo); i++) {
  1174.         if (strcmp(id, (hexlist[i]).hexname) == 0) {
  1175.             idnum = j = 254;
  1176.             hexnum = (hexlist[i]).hexvalue;
  1177.             break;
  1178.             }
  1179.         }
  1180.     }
  1181. if (j < 0) {
  1182.     sprintf(errtext, "Invalid key or function name '%s' at line %d:",
  1183.         id, lineno);
  1184.     showerrln(errtext, text);
  1185.     return(16);
  1186.     }
  1187.  
  1188. tabptr2 = 0;
  1189. switch(valtype) {
  1190.     case 0:        tabptr1 = ascbuffn;
  1191.                 taboff1 = 5*128;
  1192.                 tabptr2 = ascbuffs;
  1193.                 taboff2 = 7*128;
  1194.                 break;
  1195.     case 1:        tabptr1 = ascbuffn;
  1196.                 taboff1 = 5*128;
  1197.                 break;
  1198.     case 2:        tabptr1 = ascbuffs;
  1199.                 taboff1 = 7*128;
  1200.                 break;
  1201.     case 3:        tabptr1 = ascbuffc;
  1202.                 taboff1 = 9*128;
  1203.                 break;
  1204.     case 4:        tabptr1 = ascbuffcs;
  1205.                 taboff1 = 11*128;
  1206.                 break;
  1207.     case 5:        tabptr1 = ascbuffo;
  1208.                 taboff1 = 13*128;
  1209.                 break;
  1210.     case 6:        tabptr1 = keybuffn;
  1211.                 taboff1 = 0;
  1212.                 break;
  1213.     case 7:        tabptr1 = keybuffn;
  1214.                 taboff1 = 0;
  1215.                 break;
  1216.     case 8:        tabptr1 = keybuffs;
  1217.                 taboff1 = 128;
  1218.                 break;
  1219.     case 9:        tabptr1 = keybuffc;
  1220.                 taboff1 = 2*128;
  1221.                 break;
  1222.     case 10:    tabptr1 = keybuffcs;
  1223.                 taboff1 = 3*128;
  1224.                 break;
  1225.     case 11:    tabptr1 = keybuffo;
  1226.                 taboff1 = 4*128;
  1227.                 break;
  1228.     default:
  1229.             return(20);        /* can't happen */
  1230.             break;
  1231.     }
  1232.  
  1233. tabptr1 += valnum;
  1234. if ((*tabptr1) == 0) {
  1235.     (*tabptr1) = idnum + 1;
  1236.     if (hexnum > 0) {
  1237.         if (hexcount == 256) {
  1238.             sprintf(errtext, "Number of hex mappings exceeds 256 at line %d:",
  1239.                 lineno);
  1240.             showerrln(errtext, text);
  1241.             return(16);
  1242.             }
  1243.         (hexbuff[hexcount]).offset = taboff1 + valnum;
  1244.         (hexbuff[hexcount]).stdchar = hexnum;
  1245.         (hexbuff[hexcount++]).aplchar = 0;
  1246.         }
  1247.     }
  1248. else {
  1249.     sprintf(errtext, "Duplicate key definition at line %d:",
  1250.         lineno);
  1251.     showerrln(errtext, text);
  1252.     return(24);
  1253.     }
  1254.  
  1255. if (tabptr2 != 0) {
  1256.     tabptr2 += valnum;
  1257.     if ((*tabptr2) == 0) {
  1258.         (*tabptr2) = idnum + 1;
  1259.         if (hexnum > 0) {
  1260.             if (hexcount == 256) {
  1261.                 sprintf(errtext, "Number of hex mappings exceeds 256 at line %d:",
  1262.                     lineno);
  1263.                 showerrln(errtext, text);
  1264.                 return(16);
  1265.                 }
  1266.             (hexbuff[hexcount]).offset = taboff2 + valnum;
  1267.             (hexbuff[hexcount]).stdchar = hexnum;
  1268.             (hexbuff[hexcount++]).aplchar = 0;
  1269.             }
  1270.         }
  1271.     else {
  1272.         sprintf(errtext, "Duplicate key definition at line %d:",
  1273.             lineno);
  1274.         showerrln(errtext, text);
  1275.         return(24);
  1276.         }
  1277.     }
  1278. return (0);
  1279. }
  1280.  
  1281. pascal unsigned short onlydata(FileParam *_pb)
  1282. {
  1283. if (_pb->ioFlLgLen == 0L) return(0x100);
  1284.     else return(0);
  1285. }
  1286.  
  1287. void writetext(void)            /* write resource to Rez format file */
  1288. {
  1289. Point where;
  1290. DlgHookProcPtr dlgHook;
  1291. SFReply reply;
  1292. OSErr rc;
  1293. short fnum;
  1294. unsigned char outtext[256];
  1295. long outcount;
  1296.  
  1297. where = sfppoint;
  1298. dlgHook = 0;
  1299. strcpy(outtext, mapname);
  1300. strcat(outtext, ".r");
  1301. c2pstr(outtext);
  1302. SFPutFile(where, "\pSave in Rez format as:",
  1303.           outtext, dlgHook, &reply);
  1304. p2cstr(outtext);
  1305. if (reply.good == 0) return;
  1306. rc = FSDelete(&reply.fName, reply.vRefNum);        /* delete existing file */
  1307. rc = Create(&reply.fName, reply.vRefNum, 'MPS ', 'TEXT');
  1308. if (rc != 0) {
  1309.     sprintf(outtext, "Error %d creating output file.", rc);
  1310.     showerr(outtext);
  1311.     return;
  1312.     }
  1313. rc = FSOpen(&reply.fName, reply.vRefNum, &fnum);
  1314. if (rc != 0) {
  1315.     sprintf(outtext, "Error %d opening output file.", rc);
  1316.     showerr(outtext);
  1317.     return;
  1318.     }
  1319.     
  1320. sprintf(outtext, "data \'GFKB\' (%d, \"%s\", preload) {\n", 
  1321.     mapnum, mapname);
  1322. outcount = strlen(outtext);
  1323. rc = FSWrite(fnum, &outcount, outtext);
  1324.  
  1325. if (rc == 0) 
  1326.     rc = writearray("keybuffn", keybuffn, 128, fnum);
  1327. if (rc == 0) 
  1328.     rc = writearray("keybuffs", keybuffs, 128, fnum);
  1329. if (rc == 0) 
  1330.     rc = writearray("keybuffc", keybuffc, 128, fnum);
  1331. if (rc == 0)
  1332.     rc = writearray("keybuffcs", keybuffcs, 128, fnum);
  1333. if (rc == 0) 
  1334.     rc = writearray("keybuffo", keybuffo, 128, fnum);
  1335. if (rc == 0) 
  1336.     rc = writearray("ascbuffn", ascbuffn, 256, fnum);
  1337. if (rc == 0) 
  1338.     rc = writearray("ascbuffs", ascbuffs, 256, fnum);
  1339. if (rc == 0) 
  1340.     rc = writearray("ascbuffc", ascbuffc, 256, fnum);
  1341. if (rc == 0)
  1342.     rc = writearray("ascbuffcs", ascbuffcs, 256, fnum);
  1343. if (rc == 0) 
  1344.     rc = writearray("ascbuffo", ascbuffo, 256, fnum);
  1345. if ((hexcount > 0) && (rc == 0))
  1346.     rc = writehex(fnum);
  1347.  
  1348. if (rc == 0) {
  1349.     sprintf(outtext, "};\n");
  1350.     outcount = strlen(outtext);
  1351.     rc = FSWrite(fnum, &outcount, outtext);
  1352.     }
  1353.     
  1354. if (rc != 0) {
  1355.     sprintf(outtext, "Error %d writing output file.", rc);
  1356.     showerr(outtext);
  1357.     }
  1358.  
  1359. FSClose(fnum);
  1360. }
  1361.     
  1362. OSErr writearray(unsigned char *name, unsigned char *a, short len, short fnum)
  1363. {
  1364. OSErr rc;
  1365. long outcount;
  1366. register int i, j;
  1367. unsigned char outtext[256];
  1368.  
  1369. sprintf(outtext, "\t\t\t\t\t\t\t\t\t\t\t/* %s */\n", name);
  1370. outcount = strlen(outtext);
  1371. rc = FSWrite(fnum, &outcount, outtext);
  1372. if (rc != 0) return(rc);
  1373.  
  1374. for (i = 0; i < len; i +=16) {
  1375.     sprintf(outtext, 
  1376. "$\"%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\"\n",
  1377.     a[i], a[i+1], a[i+2], a[i+3], a[i+4], a[i+5], a[i+6], a[i+7],
  1378.     a[i+8], a[i+9], a[i+10], a[i+11], a[i+12], a[i+13], a[i+14], a[i+15]);
  1379.     for (j=0; j < strlen(outtext); j++)
  1380.         outtext[j] = toupper(outtext[j]);
  1381.     outcount = strlen(outtext);
  1382.     rc = FSWrite(fnum, &outcount, outtext);
  1383.     if (rc != 0) return(rc);
  1384.     }
  1385. return(0);
  1386. }
  1387.  
  1388. OSErr writehex(short fnum)
  1389. {
  1390. OSErr rc;
  1391. long outcount;
  1392. register int i, j;
  1393. unsigned char outtext[256];
  1394. unsigned char *a;
  1395. int wholelines, extrawords;
  1396. unsigned char wordbuff[12];
  1397.  
  1398. sprintf(outtext, "\t\t\t\t\t\t\t\t\t\t\t/* %s */\n", "hexbuff");
  1399. outcount = strlen(outtext);
  1400. rc = FSWrite(fnum, &outcount, outtext);
  1401. if (rc != 0) return(rc);
  1402.  
  1403. wholelines = hexcount / 4;
  1404. extrawords = hexcount % 4;
  1405. a = (unsigned char *)hexbuff;
  1406. i = 0;
  1407. if (wholelines > 0) {
  1408.     for (i = 0; i < wholelines*16; i +=16) {
  1409.         sprintf(outtext, 
  1410.     "$\"%02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x\"\n",
  1411.         a[i], a[i+1], a[i+2], a[i+3], a[i+4], a[i+5], a[i+6], a[i+7],
  1412.         a[i+8], a[i+9], a[i+10], a[i+11], a[i+12], a[i+13], a[i+14], a[i+15]);
  1413.         for (j=0; j < strlen(outtext); j++)
  1414.             outtext[j] = toupper(outtext[j]);
  1415.         outcount = strlen(outtext);
  1416.         rc = FSWrite(fnum, &outcount, outtext);
  1417.         if (rc != 0) return(rc);
  1418.         }
  1419.     }
  1420. if (extrawords > 0) {
  1421.     strcpy(outtext, "$\"");
  1422.     for (j = 0; j < extrawords; j++) {
  1423.         if (j > 0) strcat(outtext, " ");
  1424.         sprintf(wordbuff, "%02x%02x %02x%02x", a[i], a[i+1], a[i+2], a[i+3]);
  1425.         strcat(outtext, wordbuff);
  1426.         i += 4;
  1427.         }
  1428.     strcat(outtext, "\"\n");
  1429.     for (j=0; j < strlen(outtext); j++)
  1430.         outtext[j] = toupper(outtext[j]);
  1431.     outcount = strlen(outtext);
  1432.     rc = FSWrite(fnum, &outcount, outtext);
  1433.     if (rc != 0) return(rc);
  1434.     }
  1435. return(0);
  1436. }
  1437.  
  1438. void writersc(unsigned char new)
  1439. {
  1440. Point where;
  1441. DlgHookProcPtr dlgHook;
  1442. FileFilterProcPtr fileFilter;
  1443. SFReply reply;
  1444. short numTypes;
  1445. SFTypeList typeList;
  1446. OSErr rc;
  1447. unsigned char errtext[256];
  1448. short currvol, rfile;
  1449. Handle temph;
  1450. short i, newnum, resid, rescount;
  1451. ResType restype;
  1452. unsigned char resname[256];
  1453. char resexists;
  1454. Size mapsize;
  1455. unsigned char * sourceptr, *destptr;
  1456. unsigned short resattr;
  1457.  
  1458. if (new) {                /* create new file */
  1459.     where = sfppoint;
  1460.     dlgHook = 0;
  1461.     c2pstr(mapname);
  1462.     SFPutFile(where, "\pNew resource file:",
  1463.               mapname, dlgHook, &reply);
  1464.     p2cstr(mapname);
  1465.     if (reply.good == 0) return;
  1466.     rc = FSDelete(&reply.fName, reply.vRefNum);        /* delete existing file */
  1467.     rc = Create(&reply.fName, reply.vRefNum, 'GFKM', 'GFKB');
  1468.     if (rc != 0) {
  1469.         sprintf(errtext, "Error %d creating output file.", rc);
  1470.         showerr(errtext);
  1471.         return;
  1472.         }
  1473.     }
  1474. else {                    /* get existing resource file */
  1475.     where = sfgpoint;
  1476.     dlgHook = 0;
  1477.     fileFilter = 0;
  1478.     numTypes = 2;
  1479.     typeList[0] = 'APPL';
  1480.     typeList[1] = 'GFKB';
  1481.     SFGetFile(where, "\p", fileFilter, numTypes,
  1482.         &typeList, dlgHook, &reply);
  1483.     if (reply.good == 0) return;    /* user selected "cancel" */
  1484.     }
  1485.     
  1486. /* the file we want to open is defined by reply.fName and reply.vRefNum */
  1487.  
  1488. GetVol(errtext, &currvol);
  1489. SetVol(0L, reply.vRefNum);
  1490. rfile = OpenResFile(&reply.fName);
  1491. newnum = 0;        
  1492. resexists = 0;
  1493. if (rfile != -1) {
  1494.     rescount = CountResources('GFKB');
  1495.     if (rescount > 0) {
  1496.         for (i=1; i <= rescount; i++) {
  1497.             SetResLoad(0);            /* don't load resources */
  1498.             temph = GetIndResource('GFKB', i);
  1499.             SetResLoad(0x101);        /* restore loading */
  1500.             if (HomeResFile(temph) != rfile) break;
  1501.             GetResInfo(temph, &resid, &restype, resname);
  1502.             c2pstr(mapname);
  1503.             if (EqualString(resname, mapname, 0, 0x101) != 0) {
  1504.                 p2cstr(mapname);
  1505.                 resexists = 1;
  1506.                 break;
  1507.                 }
  1508.             else {
  1509.                 p2cstr(mapname);
  1510.                 if (resid > newnum) newnum = resid;
  1511.                 }
  1512.             }
  1513.         }
  1514.     }
  1515.  
  1516. if (resexists) newnum = resid;
  1517. else {
  1518.     if (newnum < 128) newnum = 128;
  1519.     else newnum++;
  1520.     }
  1521.  
  1522. if (resexists) {
  1523.     UseResFile(myresfile);
  1524.     rc = replacedlg(resname);
  1525.     UseResFile(rfile);
  1526.     if (rc) {
  1527.         RmveResource(temph);
  1528.         if (rc = ResError()) {
  1529.             CloseResFile(rfile);
  1530.             SetVol(0L, currvol);
  1531.             sprintf(errtext, "Error %d deleting resource from file", rc);
  1532.             showerr(errtext);
  1533.             return;
  1534.             }
  1535.         }
  1536.     else {
  1537.         CloseResFile(rfile);
  1538.         SetVol(0L, currvol);
  1539.         return;
  1540.         }
  1541.     }
  1542. if (rfile != -1) CloseResFile(rfile);
  1543.  
  1544. CreateResFile(&reply.fName);
  1545. rfile = OpenResFile(&reply.fName);
  1546. if (rfile == -1) {
  1547.     SetVol(0L, currvol);
  1548.     sprintf(errtext, "Error %d opening resource file", ResError());
  1549.     showerr(errtext);
  1550.     return;
  1551.     }
  1552.     
  1553. /* get handle to data to write out */
  1554. mapsize = sizeof(keybuffn);
  1555. mapsize += sizeof(keybuffs);
  1556. mapsize += sizeof(keybuffc);
  1557. mapsize += sizeof(keybuffcs);
  1558. mapsize += sizeof(keybuffo);
  1559. mapsize += sizeof(ascbuffn);
  1560. mapsize += sizeof(ascbuffs);
  1561. mapsize += sizeof(ascbuffc);
  1562. mapsize += sizeof(ascbuffcs);
  1563. mapsize += sizeof(ascbuffo);
  1564. mapsize += sizeof(hexmap) * hexcount;
  1565. temph = NewHandle(mapsize);
  1566. if (temph == 0) {
  1567.     CloseResFile(rfile);
  1568.     SetVol(0L, currvol);
  1569.     sprintf(errtext, "Out of memory allocating resource");
  1570.     showerr(errtext);
  1571.     return;
  1572.     }
  1573.  
  1574. destptr = *temph;
  1575.  
  1576. sourceptr = keybuffn;
  1577. memcpy(destptr, sourceptr, sizeof(keybuffn));
  1578. destptr += sizeof(keybuffn);
  1579.  
  1580. sourceptr = keybuffs;
  1581. memcpy(destptr, sourceptr, sizeof(keybuffs));
  1582. destptr += sizeof(keybuffs);
  1583.  
  1584. sourceptr = keybuffc;
  1585. memcpy(destptr, sourceptr, sizeof(keybuffc));
  1586. destptr += sizeof(keybuffc);
  1587.  
  1588. sourceptr = keybuffcs;
  1589. memcpy(destptr, sourceptr, sizeof(keybuffcs));
  1590. destptr += sizeof(keybuffcs);
  1591.  
  1592. sourceptr = keybuffo;
  1593. memcpy(destptr, sourceptr, sizeof(keybuffo));
  1594. destptr += sizeof(keybuffo);
  1595.  
  1596. sourceptr = ascbuffn;
  1597. memcpy(destptr, sourceptr, sizeof(ascbuffn));
  1598. destptr += sizeof(ascbuffn);
  1599.  
  1600. sourceptr = ascbuffs;
  1601. memcpy(destptr, sourceptr, sizeof(ascbuffs));
  1602. destptr += sizeof(ascbuffs);
  1603.  
  1604. sourceptr = ascbuffc;
  1605. memcpy(destptr, sourceptr, sizeof(ascbuffc));
  1606. destptr += sizeof(ascbuffc);
  1607.  
  1608. sourceptr = ascbuffcs;
  1609. memcpy(destptr, sourceptr, sizeof(ascbuffcs));
  1610. destptr += sizeof(ascbuffcs);
  1611.  
  1612. sourceptr = ascbuffo;
  1613. memcpy(destptr, sourceptr, sizeof(ascbuffo));
  1614. destptr += sizeof(ascbuffo);
  1615.  
  1616. sourceptr = (unsigned char *)hexbuff;
  1617. memcpy(destptr, sourceptr, sizeof(hexmap) * hexcount);
  1618.  
  1619. /* Add the new resource (finally!) */
  1620.  
  1621. c2pstr(mapname);
  1622. AddResource(temph, 'GFKB', newnum, mapname);
  1623. p2cstr(mapname);
  1624. if (rc = ResError()) {
  1625.     CloseResFile(rfile);
  1626.     SetVol(0L, currvol);
  1627.     sprintf(errtext, "Error %d adding resource to file", rc);
  1628.     showerr(errtext);
  1629.     return;
  1630.     }
  1631.  
  1632. resattr = GetResAttrs(temph);
  1633. if (rc = ResError()) {
  1634.     CloseResFile(rfile);
  1635.     SetVol(0L, currvol);
  1636.     sprintf(errtext, "Error %d getting resource attributes", rc);
  1637.     showerr(errtext);
  1638.     return;
  1639.     }
  1640.  
  1641. resattr |= resPreload;
  1642.  
  1643. SetResAttrs(temph, resattr);
  1644. if (rc = ResError()) {
  1645.     CloseResFile(rfile);
  1646.     SetVol(0L, currvol);
  1647.     sprintf(errtext, "Error %d setting resource attributes", rc);
  1648.     showerr(errtext);
  1649.     return;
  1650.     }
  1651.  
  1652. CloseResFile(rfile);
  1653. if (rc = ResError()) {
  1654.     sprintf(errtext, "Error %d closing resource to file", rc);
  1655.     showerr(errtext);
  1656.     }
  1657. SetVol(0L, currvol);
  1658. return;
  1659. }
  1660.  
  1661. OSErr replacedlg(unsigned char *resname)
  1662. {
  1663. DialogPtr dlgptr;
  1664. DialogPeek dStorage;
  1665. WindowPtr behind;
  1666. unsigned short (*filterProc) ();
  1667. short itemHit;
  1668. static char nullstr[1] = {0};
  1669.  
  1670. dStorage = 0;
  1671. behind = (WindowPtr)-1;
  1672. ParamText(resname, nullstr, nullstr, nullstr);
  1673. dlgptr = GetNewDialog(258, dStorage, behind);
  1674. ctrwindow(dlgptr);
  1675. ShowWindow(dlgptr);
  1676.  
  1677. /* frame the default selection */
  1678. framedflt(dlgptr);
  1679.  
  1680. filterProc = 0;
  1681. ModalDialog((ModalFilterProcPtr)filterProc, &itemHit);
  1682. DisposDialog(dlgptr);
  1683. ParamText(nullstr, nullstr, nullstr, nullstr);
  1684. if (itemHit == 2) return(1);
  1685. else return(0);
  1686. }
  1687.  
  1688. void showinfo(void)
  1689. {
  1690. DialogPtr dlgptr;
  1691. DialogPeek dStorage;
  1692. WindowPtr behind;
  1693. unsigned short (*filterProc) ();
  1694. short itemHit;
  1695. static char nullstr[1] = {0};
  1696. unsigned char numtext[32];
  1697. unsigned char datestr[516];
  1698. short datelen;
  1699. FileParam fp;
  1700.  
  1701. fp.ioNamePtr = &defreply.fName;
  1702. fp.ioVRefNum = defreply.vRefNum;
  1703. fp.ioFVersNum = 0;
  1704. fp.ioFDirIndex = 0;
  1705. PBGetFInfo((ParmBlkPtr)&fp, 0);
  1706. IUDateString(fp.ioFlMdDat, 2, datestr);
  1707. p2cstr(datestr);
  1708. strcat(datestr, "  ");
  1709. datelen = strlen(datestr);
  1710. IUTimeString(fp.ioFlMdDat, 1, datestr+datelen);
  1711. p2cstr(datestr+datelen);
  1712.  
  1713. sprintf(numtext, "%d", mapnum);
  1714.  
  1715. c2pstr(datestr);
  1716. c2pstr(mapname);
  1717. c2pstr(numtext);
  1718. ParamText(&defreply.fName, datestr, mapname, numtext);
  1719. p2cstr(datestr);
  1720. p2cstr(mapname);
  1721. p2cstr(numtext);
  1722. dStorage = 0;
  1723. behind = (WindowPtr)-1;
  1724. dlgptr = GetNewDialog(259, dStorage, behind);
  1725. ctrwindow(dlgptr);
  1726. ShowWindow(dlgptr);
  1727.  
  1728. /* frame the default selection */
  1729. framedflt(dlgptr);
  1730.  
  1731. filterProc = 0;
  1732. ModalDialog((ModalFilterProcPtr)filterProc, &itemHit);
  1733. DisposDialog(dlgptr);
  1734. ParamText(nullstr, nullstr, nullstr, nullstr);
  1735. }
  1736.